# vim: set fileencoding=utf8 :
import datetime
import BoletoDadosException
import re

class BoletoDados:
    
    def __init__(self):
        self.__localPagamento = "Pagável em qualquer banco até o vencimento"
        self.__cedente = ""
        self.__dataDocumento = ""
        self.__numeroDocumento = ""
        self.__especieDocumento = ""
        self.__aceite = "N"
        self.__dataProcessamento = ""
        self.__carteira = ""
        self.__especie = "R$"
        self.__quantidade = ""
        self.__valor = None
        self.__valorDocumento = None
        self.__dataVencimento = ""
        self.__agenciaCedente = ""
        self.__contaCedente = ""
        self.__nossoNumero = ""
        self.__instrucoes = []
        self.__sacado = []
        self.__codigoBanco = ""
        self.__moeda = "9"
        self.__demonstrativo = []
        self.__sacadoNome = ""
        self.__sacadoEndereco = ""
        self.__sacadoBairro = ""
        self.__sacadoCep = ""
        self.__sacadoSufixoCep = ""
        self.__sacadoCidade = ""
        self.__sacadoUf = ""
        self.__sacadoCpf = ""
        self.__sacadoCnpj = ""
    
    def setLocalPagamento(self, txt):
        self.__localPagamento = txt

    def setCedente(self, txt):
        self.__cedente = txt
    
    def setDataDocumento(self, txt):
        self.__dataDocumento = txt
    
    def setNumeroDocumento(self, txt):
        self.__numeroDocumento = txt
    
    def setEspecieDocumento(self, txt):
        self.__especieDocumento = txt
    
    def setAceite(self, txt):
        self.__aceite = txt
    
    def setDataProcessamento(self, txt):
        self.__dataProcessamento = txt
    
    def setCarteira(self, txt):
        self.__carteira = txt
    
    def setEspecie(self, txt):
        self.__especie = txt
   
    def setQuantidade(self, txt):
        self.__quantidade = txt
    
    def setValor(self, nfloat):
        self.__valor = nfloat

    def setValorDocumento(self, nfloat):
        self.__valorDocumento = nfloat
    
    def setDataVencimento(self, txt):
        self.__dataVencimento = txt
    
    def setAgenciaCedente(self, txt):
        self.__agenciaCedente = txt
    
    def setContaCedente(self, txt):
        self.__contaCedente = txt
    
    def setNossoNumero(self, txt):
        self.__nossoNumero = txt
    
    def setInstrucoes(self, listTxt):
        """ Just 7 lines and 90 characters each line """
        listTxt = listTxt[0:7]
        for i in range(len(listTxt)):
            listTxt[i] = listTxt[i][0:90]
            
        self.__instrucoes = listTxt
    
    def setDemonstrativo(self, listTxt):
        """ Just 12 lines and 90 characters each line """
        #listTxt = listTxt[0:12]
        for i in range(len(listTxt)):
            listTxt[i] = listTxt[i][0:90]
            
        self.__demonstrativo = listTxt
    
    def setSacado(self, listTxt):
        """ Just 3 lines and 80 characters each line """
        listTxt = listTxt[0:3]
        for i in range(len(listTxt)):
            listTxt[i] = listTxt[i][0:80]
        
        self.__sacado = listTxt
        
    def setCodigoBanco(self, txt):
        self.__codigoBanco = txt
    
    def setSacadoNome(self, txt ):
        self.__sacadoNome = txt
        
    def setSacadoEndereco(self, txt):
        self.__sacadoEndereco = txt
        
    def setSacadoBairro(self, txt):
        self.__sacadoBairro = txt
        
    def setSacadoCep(self, txt):
        r = re.search( '(\d{5})-(\d{3})' )
        if not r:
            raise BoletoDadosException.BoletoDadosException( 'O cep deve ter o seguinte formato XXXXX-XXX' )
        self.__sacadoCep = r.group(1)
        self.__sacadoSufixoCep = r.group(2)
        
    def setSacadoCidade(self, txt):
        self.__sacadoCidade = txt
        
    def setSacadoUf(self, txt):
        self.__sacadoUf = txt
        
    def setSacadoCpf(self, txt):
        self.__sacadoCpf = txt
        
    def setSacadoCnpj(self, txt):
        self.__sacadoCnpj = txt

    def getLocalPagamento(self):
        return self.__localPagamento

    def getCedente(self):
        return self.__cedente
        
    def getDataDocumento(self):
        return self.__dataDocumento
    
    def getNumeroDocumento(self):
        return self.__numeroDocumento
    
    def getEspecieDocumento(self):
        return self.__especieDocumento
    
    def getAceite(self):
        return self.__aceite
    
    def getDataProcessamento(self):
        return self.__dataProcessamento
    
    def getCarteira(self):
        return self.__carteira
    
    def getEspecie(self):
        return self.__especie
   
    def getQuantidade(self):
        return self.__quantidade
    
    def getValor(self):
        return self.__valor

    def getValorDocumento(self):
        return self.__valorDocumento
    
    def getDataVencimento(self):
        return self.__dataVencimento
    
    def getAgenciaCedente(self):
        return self.__agenciaCedente
    
    def getContaCedente(self):
        return self.__contaCedente
    
    def getNossoNumero(self):
        return self.__nossoNumero
    
    def getInstrucoes(self):
        return self.__instrucoes
    
    def getDemonstrativo(self):
        return self.__demonstrativo

    def getSacado(self):
        if not self.__sacado:
            s = []
            s.append( self.getSacadoNome() )
            s.append( self.getSacadoEndereco() )
            s.append( "%s - %s - %s - %s" % (self.getSacadoBairro(), self.getSacadoCidade(), self.getSacadoUf(), self.getSacadoCep()) )
            self.setSacado(s)
        return self.__sacado

    def getCodigoBanco(self):
        return self.__codigoBanco
    
    def getSacadoNome(self):
        return self.__sacadoNome
        
    def getSacadoEndereco(self):
        return self.__sacadoEndereco
        
    def getSacadoBairro(self):
        return self.__sacadoBairro
        
    def getSasadoCep(self):
        return self.__sacadoCep
        
    def getSacadoCidade(self):
        return self.__sacadoCidade
        
    def getSacadoUf(self):
        return self.__sacadoUf
        
    def getSacadoCpf(self):
        return self.__sacadoCpf
        
    def getSacadoCnpj(self):
        return self.__sacadoCnpj
    
    def getMoeda(self):
        return self.__moeda
    
    def getCodigoDvBanco(self):
        return "";
        
    def getAgenciaContaCedente(self):
        return "%s/%s" % (self.__agenciaCedente, self.__codigoCendente)

    def getLinhaDigitavel(self):
        return ""
    
    def getImgCodigoBarra(self):
        return None
    
    def getLogoImagePath(self):
        return None
    
    def formataNumero(self, numero, tamanho):
        if len(numero) > tamanho:
            raise BoletoDadosException.BoletoDadosException( 'Tamanho em caracteres do número está maior que o permitido' )
        return numero.zfill(tamanho)
    
    def formataTexto(self, texto, tamanho):
        if len(texto) > tamanho:
            raise BoletoDadosException.BoletoDadosException( 'Tamanho em caracteres do texto está maior que o permitido' )
        return texto.ljust(tamanho)
    
    def formataValor(self, nfloat, tamanho):
        txt = "%.2f" % nfloat
        txt = txt.replace( '.', '' )
        txt = self.formataNumero(txt, tamanho)
        return txt
    
    def _modulo10(self, num):
        soma = 0
        peso = 2
        for i in range(len(num)-1,-1,-1):
            parcial = int(num[i]) * peso
            if parcial > 9:
                s = "%d" % parcial
                parcial = int(s[0])+int(s[1])
            soma += parcial
            if peso == 2:
                peso = 1
            else:
                peso = 2
        
        resto10 = soma % 10
        if resto10 == 0:
            modulo10 = 0
        else:
            modulo10 = 10 - resto10
            
        return modulo10

    def _modulo11(self,num):
        soma = 0
        peso = 2
        for i in range(len(num)-1,-1,-1):
            parcial = int(num[i]) * peso
            soma += parcial
            if peso == 9:
                peso = 2
            else:
                peso += 1
        
        resto11 = soma % 11
        if resto11 == 0 or resto11 == 1:
            modulo11 = 1
        else:
            modulo11 = 11 - resto11
            
        return modulo11
    
    def _fatorVencimento(self, data):
        data = data.split("/")
        ano = int(data[2])
        mes = int(data[1])
        dia = int(data[0])
        
        dateReferencia = datetime.date(2000,7,3) # Fator = 1000
        dateVencimento = datetime.date(ano,mes,dia)
        
        delta = dateVencimento - dateReferencia
        fator = delta.days + 1000
        
        return fator
